package com.treeliked.udpdemo.service.impl;

import com.treeliked.udpdemo.ThreadPoolExecutorFactory;
import com.treeliked.udpdemo.cs.BaseClientServer;
import com.treeliked.udpdemo.cs.UdpClient;
import com.treeliked.udpdemo.model.Constant;
import com.treeliked.udpdemo.model.Message;
import com.treeliked.udpdemo.page.p1.Client;
import com.treeliked.udpdemo.util.MessageUtils;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

/**
 * udp服务实现类
 *
 * @author lss
 * @date 2019-01-03, Thu
 */
public class ClientServiceImpl extends AbstractUdpServiceImpl {

    private DatagramSocket ds;

    /**
     * server post
     */
    private int serverPort;

    private Client client;

    private boolean receiveFlag = false;

    public ClientServiceImpl(DatagramSocket ds, int serverPort, Client client) {
        super(ds);
        this.ds = ds;
        this.serverPort = serverPort;
        this.client = client;
    }


    @Override
    public void send(Message msg) throws IOException {
        client.addSendMessageAmount();
        super.send(msg);
    }

    @Override
    public void startReceive(BaseClientServer cs) throws IOException {
        receiveFlag = true;
        ThreadPoolExecutorFactory.getThreadPoolExecutor().execute(() -> {
            while (receiveFlag) {
                byte[] buf = new byte[Constant.BUFFER_SIZE];
                DatagramPacket packet = new DatagramPacket(buf, buf.length);
                try {
                    ds.receive(packet);
                    Message msg = MessageUtils.bytesToMessage(packet.getData());
                    client.addReceiveMessageAmount();
                    client.addReceiveMessage(msg);
                    if (msg.getMsgType() == Message.MESSAGE_TYPE_ACK) {
                        if (msg.getAckResult() == Message.ACK_RESULT_RESEND) {
                            UdpClient uc = (UdpClient) cs;
                            uc.stopReceive();
                            // 重发消息，发送失败消息的id封装在;content中
                            Message messageById = uc.getMessageById(msg.getContent());
                            send(messageById);
                            uc.startReceive();
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }


    @Override
    public void stopReceive() throws IOException {
        receiveFlag = false;
    }

}

